/*
 * 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。[遇见知启蒙，邂逅框架梦，本文采用木兰宽松许可证第2版]
 * 
 * https://zhiqim.org/project/zhiqim_kit/zhiqim_git.htm
 *
 * ZhiqimGit is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
package org.zhiqim.git.objer.model;

import java.util.ArrayList;
import java.util.List;

import org.zhiqim.git.GitConstants;
import org.zhiqim.git.objer.objectid.ObjectId;

import org.zhiqim.kernel.util.mutables.MInt;
import org.zhiqim.kernel.util.Bytes;
import org.zhiqim.kernel.util.Ints;
import org.zhiqim.kernel.util.Lists;

/**
 * 树模型对象，格式：${fileMode}空格${name}\0${oid}<br>
 * 100644 GitConstants.java\0a179adfdf64304072280512cd31fc9f45d181390<br>
 * 160000 Zhiqim\ec088c107d7970650fadac376ab6b77d3c37dd05<br>
 * 40000 新建文件夹\0bba05a7f4a8af79105d375dc440f8d48a3cdbaf4<br>
 * 
 * @version v1.0.0 @author zouzhigang 2017-4-24 新建与整理
 */
public class Tree implements GitConstants
{
    private String folder;
    private List<TreeEntry> folderList;
    private List<TreeEntry> fileList;
    
    public Tree()
    {
        folderList = new ArrayList<>();
        fileList = new ArrayList<>();
    }
    
    /******************************************************************************/
    //树参数获取&设置
    /******************************************************************************/
    
    public Tree setFolder(String folder)
    {
        this.folder = folder;
        return this;
    }
    
    public String getFolder()
    {
        return folder == null?"":folder;
    }
    
    public List<TreeEntry> list()
    {
        List<TreeEntry> list = new ArrayList<>(fileList);
        list.addAll(folderList);
        return list;
    }
    
    public List<TreeEntry> getFileList()
    {
        return fileList;
    }

    public List<TreeEntry> getFolderList()
    {
        return folderList;
    }
    
    public TreeEntry getFolder(String folder)
    {
        for (TreeEntry entry : folderList)
        {
            if (entry.getName().equals(folder))
                return entry;
        }
        
        return null;
    }
    
    public boolean has(Object oid)
    {
        for (TreeEntry entry : folderList)
        {
            if (entry.getOid().equals(oid))
                return true;
        }
        
        for (TreeEntry entry : fileList)
        {
            if (entry.getOid().equals(oid))
                return true;
        }
        
        return false;
    }
    
    public boolean isEmpty()
    {
        return folderList.isEmpty() && fileList.isEmpty();
    }
    
    /******************************************************************************/
    //解析&生成
    /******************************************************************************/
    
    /** 解析 */
    public Tree parse(byte[] content)
    {
        int size = content.length;
        MInt off = new MInt();
        
        while (off.value < size)
        {//依次读取条目，每条目格式：${mode} ${name}\0${oid}
            
            String mode = Bytes.BU.getString(content, off, ' ');
            String name = Bytes.BU.getString(content, off, (byte)0);
            byte[] oid = Bytes.getBytes(content, off, 20);
            
            TreeEntry entry = new TreeEntry(this, Ints.toInt(mode), name, ObjectId.parse(oid));
            if (entry.isFolder())
                folderList.add(entry);
            else
                fileList.add(entry);
        }
        
        Lists.trim(folderList);
        Lists.trim(fileList);
        return this;
    }
    
    /******************************************************************************/
    //toString
    /******************************************************************************/
    
    public String toString()
    {
        StringBuilder strb = new StringBuilder();
        strb.append("树(").append(folder).append(")").append(_BR_);
        
        strb.append("[").append(_BR_);
        for (TreeEntry entry : folderList){
            strb.append(entry).append(_BR_);
        }
        
        for (TreeEntry entry : fileList){
            strb.append(entry).append(_BR_);
        }
        strb.append("]");
        
        return strb.toString();
    }
}
